]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
workspacesView: Simplify the workspacesOnlyOnPrimary implementation
authorJasper St. Pierre <jstpierre@mecheye.net>
Wed, 11 Sep 2013 16:12:42 +0000 (12:12 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Wed, 30 Oct 2013 17:17:39 +0000 (13:17 -0400)
Before, workspacesOnlyOnPrimary was implemented in quite a crazy manner:

 * If workspacesOnlyOnPrimary was false, we'd create one WorkspacesView per
   monitor, with the primary one being a bit special.

 * If workspacesOnlyOnPrimary was true, we'd create one WorkspacesView, and
   additional montiors would be handled inside that WorkspacesView as
   "extra workspaces".

This caused numerous bugs as the two modes weren't consistently
implemented, and a lot of code was duplicated between all the modes.
Fix this by always creating WorkspaceViews, even if it only handles
one interface. We do this by having two different WorkspacesView-ish
classes: WorkspacesView handles the traditional combination of lots
of workspces, and a new ExtraWorkspaceView is in control of only one
workspace.

js/ui/workspacesView.js

index 26dfed63e2f78ab89fa7ee904ba750f72c480e3e..31d61441ccfb919d200bb35e427622524752abc2 100644 (file)
@@ -23,27 +23,75 @@ const MAX_WORKSPACES = 16;
 
 const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
 
-const WorkspacesView = new Lang.Class({
-    Name: 'WorkspacesView',
+const WorkspacesViewBase = new Lang.Class({
+    Name: 'WorkspacesViewBase',
 
     _init: function(monitorIndex) {
         this.actor = new St.Widget({ style_class: 'workspaces-view',
                                      reactive: true });
+        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 
         // The actor itself isn't a drop target, so we don't want to pick on its area
         this.actor.set_size(0, 0);
 
-        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+        this._monitorIndex = monitorIndex;
 
         this._fullGeometry = null;
         this._actualGeometry = null;
 
-        this._monitorIndex = monitorIndex;
+        this._inDrag = false;
+        this._windowDragBeginId = Main.overview.connect('window-drag-begin', Lang.bind(this, this._dragBegin));
+        this._windowDragEndId = Main.overview.connect('window-drag-end', Lang.bind(this, this._dragEnd));
+    },
+
+    _onDestroy: function() {
+        this._dragEnd();
+
+        if (this._windowDragBeginId > 0) {
+            Main.overview.disconnect(this._windowDragBeginId);
+            this._windowDragBeginId = 0;
+        }
+        if (this._windowDragEndId > 0) {
+            Main.overview.disconnect(this._windowDragEndId);
+            this._windowDragEndId = 0;
+        }
+    },
+
+    _dragBegin: function(overview, clone) {
+        this._inDrag = true;
+        this._setReservedSlot(clone);
+    },
+
+    _dragEnd: function() {
+        this._inDrag = false;
+        this._setReservedSlot(null);
+    },
+
+    destroy: function() {
+        this.actor.destroy();
+    },
+
+    setFullGeometry: function(geom) {
+        this._fullGeometry = geom;
+        this._syncGeometry();
+    },
+
+    setActualGeometry: function(geom) {
+        this._actualGeometry = geom;
+        this._syncGeometry();
+    },
+});
+
+const WorkspacesView = new Lang.Class({
+    Name: 'WorkspacesView',
+    Extends: WorkspacesViewBase,
+
+    _init: function(monitorIndex) {
+        this.parent(monitorIndex);
 
         this._animating = false; // tweening
         this._scrolling = false; // swipe-scrolling
         this._animatingScroll = false; // programatically updating the adjustment
-        this._inDrag = false; // dragging a window
 
         this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
 
@@ -61,10 +109,6 @@ const WorkspacesView = new Lang.Class({
         this._updateWorkspaces();
         this._updateWorkspacesId = global.screen.connect('notify::n-workspaces', Lang.bind(this, this._updateWorkspaces));
 
-        this._extraWorkspaces = [];
-        this._updateExtraWorkspaces();
-        this._updateExtraWorkspacesId = this._settings.connect('changed::workspaces-only-on-primary', Lang.bind(this, this._updateExtraWorkspaces));
-
         this._overviewShownId =
             Main.overview.connect('shown',
                                  Lang.bind(this, function() {
@@ -75,36 +119,11 @@ const WorkspacesView = new Lang.Class({
         this._switchWorkspaceNotifyId =
             global.window_manager.connect('switch-workspace',
                                           Lang.bind(this, this._activeWorkspaceChanged));
-
-        this._windowDragBeginId = Main.overview.connect('window-drag-begin',
-                                                        Lang.bind(this, this._dragBegin));
-        this._windowDragEndId = Main.overview.connect('window-drag-end',
-                                                      Lang.bind(this, this._dragEnd));
-    },
-
-    _updateExtraWorkspaces: function() {
-        this._destroyExtraWorkspaces();
-
-        if (!this._settings.get_boolean('workspaces-only-on-primary'))
-            return;
-
-        let monitors = Main.layoutManager.monitors;
-        for (let i = 0; i < monitors.length; i++) {
-            if (i == Main.layoutManager.primaryIndex)
-                continue;
-
-            let ws = new Workspace.Workspace(null, i);
-            ws.setFullGeometry(monitors[i]);
-            ws.setActualGeometry(monitors[i]);
-            Main.layoutManager.overviewGroup.add_actor(ws.actor);
-            this._extraWorkspaces.push(ws);
-        }
     },
 
-    _destroyExtraWorkspaces: function() {
-        for (let m = 0; m < this._extraWorkspaces.length; m++)
-            this._extraWorkspaces[m].destroy();
-        this._extraWorkspaces = [];
+    _setReservedSlot: function(clone) {
+        for (let i = 0; i < this._workspaces.length; i++)
+            this._workspaces[i].setReservedSlot(clone);
     },
 
     _syncGeometry: function() {
@@ -114,16 +133,6 @@ const WorkspacesView = new Lang.Class({
             this._workspaces[i].setActualGeometry(this._actualGeometry);
     },
 
-    setFullGeometry: function(geom) {
-        this._fullGeometry = geom;
-        this._syncGeometry();
-    },
-
-    setActualGeometry: function(geom) {
-        this._actualGeometry = geom;
-        this._syncGeometry();
-    },
-
     getActiveWorkspace: function() {
         let active = global.screen.get_active_workspace_index();
         return this._workspaces[active];
@@ -132,8 +141,6 @@ const WorkspacesView = new Lang.Class({
     zoomToOverview: function() {
         for (let w = 0; w < this._workspaces.length; w++)
             this._workspaces[w].zoomToOverview();
-        for (let w = 0; w < this._extraWorkspaces.length; w++)
-            this._extraWorkspaces[w].zoomToOverview();
     },
 
     zoomFromOverview: function() {
@@ -141,19 +148,11 @@ const WorkspacesView = new Lang.Class({
 
         for (let w = 0; w < this._workspaces.length; w++)
             this._workspaces[w].zoomFromOverview();
-        for (let w = 0; w < this._extraWorkspaces.length; w++)
-            this._extraWorkspaces[w].zoomFromOverview();
-    },
-
-    destroy: function() {
-        this.actor.destroy();
     },
 
     syncStacking: function(stackIndices) {
         for (let i = 0; i < this._workspaces.length; i++)
             this._workspaces[i].syncStacking(stackIndices);
-        for (let i = 0; i < this._extraWorkspaces.length; i++)
-            this._extraWorkspaces[i].syncStacking(stackIndices);
     },
 
     _scrollToActive: function() {
@@ -270,44 +269,12 @@ const WorkspacesView = new Lang.Class({
     },
 
     _onDestroy: function() {
-        this._destroyExtraWorkspaces();
+        this.parent();
+
         this.scrollAdjustment.run_dispose();
         Main.overview.disconnect(this._overviewShownId);
         global.window_manager.disconnect(this._switchWorkspaceNotifyId);
         global.screen.disconnect(this._updateWorkspacesId);
-        this._settings.disconnect(this._updateExtraWorkspacesId);
-
-        if (this._inDrag)
-            this._dragEnd();
-
-        if (this._windowDragBeginId > 0) {
-            Main.overview.disconnect(this._windowDragBeginId);
-            this._windowDragBeginId = 0;
-        }
-        if (this._windowDragEndId > 0) {
-            Main.overview.disconnect(this._windowDragEndId);
-            this._windowDragEndId = 0;
-        }
-    },
-
-    _dragBegin: function(overview, clone) {
-        if (this._scrolling)
-            return;
-
-        this._inDrag = true;
-        for (let i = 0; i < this._workspaces.length; i++)
-            this._workspaces[i].setReservedSlot(clone);
-        for (let i = 0; i < this._extraWorkspaces.length; i++)
-            this._extraWorkspaces[i].setReservedSlot(clone);
-    },
-
-    _dragEnd: function() {
-        this._inDrag = false;
-
-        for (let i = 0; i < this._workspaces.length; i++)
-            this._workspaces[i].setReservedSlot(null);
-        for (let i = 0; i < this._extraWorkspaces.length; i++)
-            this._extraWorkspaces[i].setReservedSlot(null);
     },
 
     startSwipeScroll: function() {
@@ -366,6 +333,42 @@ const WorkspacesView = new Lang.Class({
 });
 Signals.addSignalMethods(WorkspacesView.prototype);
 
+const ExtraWorkspaceView = new Lang.Class({
+    Name: 'ExtraWorkspaceView',
+    Extends: WorkspacesViewBase,
+
+    _init: function(monitorIndex) {
+        this.parent(monitorIndex);
+        this._workspace = new Workspace.Workspace(null, monitorIndex);
+        this.actor.add_actor(this._workspace.actor);
+    },
+
+    _setReservedSlot: function(clone) {
+        this._workspace.setReservedSlot(clone);
+    },
+
+    _syncGeometry: function() {
+        this._workspace.setFullGeometry(this._fullGeometry);
+        this._workspace.setActualGeometry(this._actualGeometry);
+    },
+
+    zoomToOverview: function() {
+        this._workspace.zoomToOverview();
+    },
+
+    zoomFromOverview: function() {
+        this._workspace.zoomFromOverview();
+    },
+
+    syncStacking: function(stackIndices) {
+        this._workspace.syncStacking(stackIndices);
+    },
+
+    startSwipeScroll: function() {
+    },
+    endSwipeScroll: function() {
+    },
+});
 
 const WorkspacesDisplay = new Lang.Class({
     Name: 'WorkspacesDisplay',
@@ -481,35 +484,36 @@ const WorkspacesDisplay = new Lang.Class({
         this._workspacesViews = [];
         let monitors = Main.layoutManager.monitors;
         for (let i = 0; i < monitors.length; i++) {
+            let view;
             if (this._workspacesOnlyOnPrimary && i != this._primaryIndex)
-                continue;  // we are only interested in the primary monitor
+                view = new ExtraWorkspaceView(i);
+            else
+                view = new WorkspacesView(i);
 
-            let view = new WorkspacesView(i);
             view.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
-            if (this._workspacesOnlyOnPrimary || i == this._primaryIndex) {
+            if (i == this._primaryIndex) {
                 this._scrollAdjustment = view.scrollAdjustment;
                 this._scrollAdjustment.connect('notify::value',
                                                Lang.bind(this, this._scrollValueChanged));
             }
+
             this._workspacesViews.push(view);
+            Main.layoutManager.overviewGroup.add_actor(view.actor);
         }
 
         this._updateWorkspacesFullGeometry();
         this._updateWorkspacesActualGeometry();
-
-        for (let i = 0; i < this._workspacesViews.length; i++)
-            Main.layoutManager.overviewGroup.add_actor(this._workspacesViews[i].actor);
     },
 
     _scrollValueChanged: function() {
-        if (this._workspacesOnlyOnPrimary)
-            return;
-
         for (let i = 0; i < this._workspacesViews.length; i++) {
             if (i == this._primaryIndex)
                 continue;
 
             let adjustment = this._workspacesViews[i].scrollAdjustment;
+            if (!adjustment)
+                continue;
+
             // the adjustments work in terms of workspaces, so the
             // values map directly
             adjustment.value = this._scrollAdjustment.value;
@@ -519,10 +523,7 @@ const WorkspacesDisplay = new Lang.Class({
     _getPrimaryView: function() {
         if (!this._workspacesViews.length)
             return null;
-        if (this._workspacesOnlyOnPrimary)
-            return this._workspacesViews[0];
-        else
-            return this._workspacesViews[this._primaryIndex];
+        return this._workspacesViews[this._primaryIndex];
     },
 
     activeWorkspaceHasMaximizedWindows: function() {
@@ -568,15 +569,9 @@ const WorkspacesDisplay = new Lang.Class({
             return;
 
         let monitors = Main.layoutManager.monitors;
-        let m = 0;
         for (let i = 0; i < monitors.length; i++) {
-            if (i == this._primaryIndex) {
-                this._workspacesViews[m].setFullGeometry(this._fullGeometry);
-                m++;
-            } else if (!this._workspacesOnlyOnPrimary) {
-                this._workspacesViews[m].setFullGeometry(monitors[i]);
-                m++;
-            }
+            let geometry = (i == this._primaryIndex) ? this._fullGeometry : monitors[i];
+            this._workspacesViews[i].setFullGeometry(geometry);
         }
     },
 
@@ -587,18 +582,12 @@ const WorkspacesDisplay = new Lang.Class({
         let [x, y] = this.actor.get_transformed_position();
         let width = this.actor.allocation.x2 - this.actor.allocation.x1;
         let height = this.actor.allocation.y2 - this.actor.allocation.y1;
-        let geometry = { x: x, y: y, width: width, height: height };
+        let primaryGeometry = { x: x, y: y, width: width, height: height };
 
         let monitors = Main.layoutManager.monitors;
-        let m = 0;
         for (let i = 0; i < monitors.length; i++) {
-            if (i == this._primaryIndex) {
-                this._workspacesViews[m].setActualGeometry(geometry);
-                m++;
-            } else if (!this._workspacesOnlyOnPrimary) {
-                this._workspacesViews[m].setActualGeometry(monitors[i]);
-                m++;
-            }
+            let geometry = (i == this._primaryIndex) ? primaryGeometry : monitors[i];
+            this._workspacesViews[i].setActualGeometry(geometry);
         }
     },